using System;
using System.Text.RegularExpressions;
using System.Web.UI;
namespace JQueryControlToolkit.Controls
{
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event, Inherited = true)]
	public class JQueryElementAttribute : Attribute
	{
		public const string SELECTOR_PATTERN = "((((?<selectorType>\\.|#|\\$)(?<selector>\\w+))|(\\*|span|div|input|option|select|textarea|p|h[0-9]|body|html))(\\[\\w(=\\w)?\\])?(?<function>\\:(first|last|even|odd|((eq|gt|lt)\\([0-9]+\\))|header|animated|((not|has)\\((?<selectorParameter>.+)\\))))?( ?(\\>|\\+|\\~) ?)?)+";
		public static Regex Any = new Regex(".*");
		public static Regex SelectorRegex = new Regex("((((?<selectorType>\\.|#|\\$)(?<selector>\\w+))|(\\*|span|div|input|option|select|textarea|p|h[0-9]|body|html))(\\[\\w(=\\w)?\\])?(?<function>\\:(first|last|even|odd|((eq|gt|lt)\\([0-9]+\\))|header|animated|((not|has)\\((?<selectorParameter>.+)\\))))?( ?(\\>|\\+|\\~) ?)?)+");
		public static string VariableSelectorRegexPattern = "((((?<selectorType>\\.|#|\\$)(?<selector>\\w+))|(\\*|span|div|input|option|select|textarea|p|h[0-9]|body|html))(\\[\\w(=\\w)?\\])?(?<function>\\:(first|last|even|odd|((eq|gt|lt)\\([0-9]+\\))|header|animated|((not|has)\\((?<selectorParameter>.+)\\))))?( ?(\\>|\\+|\\~) ?)?)+".Replace("|html", "|html|{0}");
		private Control owner;
		public string JQueryElementName
		{
			get;
			set;
		}
		public string PropertyName
		{
			get;
			set;
		}
		public bool IsSelector
		{
			get;
			set;
		}
		public SerializeAs SerializeAs
		{
			get;
			set;
		}
		public Regex RegexValidation
		{
			get;
			set;
		}
		internal object DefaultValue
		{
			get;
			set;
		}
		public JQueryElementAttribute() : this(null, null, false, JQueryElementAttribute.Any)
		{
		}
		public JQueryElementAttribute(string jQueryElementName) : this(null, jQueryElementName, false, JQueryElementAttribute.Any)
		{
		}
		public JQueryElementAttribute(string jQueryElementName, Regex validation) : this(null, jQueryElementName, true, validation)
		{
		}
		public JQueryElementAttribute(bool isSelector) : this(null, null, isSelector, JQueryElementAttribute.SelectorRegex)
		{
		}
		public JQueryElementAttribute(string jQueryElementName, bool isSelector) : this(null, jQueryElementName, isSelector, isSelector ? JQueryElementAttribute.SelectorRegex : JQueryElementAttribute.Any)
		{
		}
		protected JQueryElementAttribute(string jQueryElementName, SerializeAs serializeAs) : this(null, jQueryElementName, false, serializeAs, JQueryElementAttribute.Any)
		{
		}
		public JQueryElementAttribute(string propertyName, string jQueryElementName, bool isSelector) : this(propertyName, jQueryElementName, isSelector, isSelector ? SerializeAs.String : SerializeAs.Is, isSelector ? JQueryElementAttribute.SelectorRegex : JQueryElementAttribute.Any)
		{
		}
		public JQueryElementAttribute(string propertyName, string jQueryElementName, bool isSelector, SerializeAs serializeAs, string validationPattern) : this(propertyName, jQueryElementName, isSelector, serializeAs, isSelector ? new Regex(string.Format(JQueryElementAttribute.VariableSelectorRegexPattern, validationPattern)) : new Regex(validationPattern))
		{
		}
		public JQueryElementAttribute(string propertyName, string jQueryElementName, bool isSelector, string validationPattern) : this(propertyName, jQueryElementName, isSelector, isSelector ? SerializeAs.String : SerializeAs.Is, validationPattern)
		{
		}
		public JQueryElementAttribute(string propertyName, string jQueryElementName, bool isSelector, Regex validation) : this(propertyName, jQueryElementName, isSelector, isSelector ? SerializeAs.String : SerializeAs.Is, validation)
		{
		}
		public JQueryElementAttribute(string propertyName, string jQueryElementName, bool isSelector, SerializeAs serializeAs, Regex validation)
		{
			this.PropertyName = propertyName;
			this.JQueryElementName = jQueryElementName;
			this.IsSelector = isSelector;
			this.SerializeAs = serializeAs;
			this.RegexValidation = validation;
		}
		internal bool IsMatch(string value)
		{
			return this.RegexValidation == JQueryElementAttribute.Any || this.RegexValidation.IsMatch(value);
		}
		internal object GetValue(Control owner, object value)
		{
			object result;
			if (owner == null)
			{
				result = value;
			}
			else
			{
				this.owner = owner;
				if (!this.IsSelector || value == null)
				{
					result = value;
				}
				else
				{
					result = this.GetClientSelector(value.ToString());
				}
			}
			return result;
		}
		private string GetClientSelector(string serverSelector)
		{
			return JQueryElementAttribute.SelectorRegex.Replace(serverSelector, new MatchEvaluator(this.Replacer));
		}
		private string Replacer(Match match)
		{
			string result;
			if (match.Groups["selectorType"].Value == "$")
			{
				if (match.Groups["selector"].Value == "this")
				{
					result = "#" + this.owner.ClientID;
				}
				else
				{
					result = "#" + this.owner.FindControl(match.Groups["selector"].Value).ClientID;
				}
			}
			else
			{
				result = match.Value;
			}
			return result;
		}
	}
}
